/*
 *
 *  *  Copyright (c), utrix (idea110@163.com).
 *  *  <p>
 *  *  Licensed under the GNU Lesser General Public License 3.0 (the "License");
 *  *  you may not use this file except in compliance with the License.
 *  *  You may obtain a copy of the License at
 *  *  <p>
 *  * https://www.gnu.org/licenses/lgpl.html
 *  *  <p>
 *  * Unless required by applicable law or agreed to in writing, software
 *  * distributed under the License is distributed on an "AS IS" BASIS,
 *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  * See the License for the specific language governing permissions and
 *  * limitations under the License.
 *
 */

package priv.utrix.micro.json;

import cn.hutool.http.HttpStatus;
import com.google.common.base.Strings;
import priv.utrix.micro.constant.ResultCode;

import java.io.Serializable;

/**
 * 接口统一返回类
 *
 * @author utrix
 * @since 2020/9/22 15:20
 */
public class R<T> implements Serializable {

    private static final long serialVersionUID = -8853873028488023513L;

    /**
     * <pre>
     * json返回代号
     * 仅限制是HttpStatus的属性值
     * </pre>
     */
    private long code;
    /**
     * 返回的数据
     */
    private T data;
    /**
     * 返回的异常信息
     */
    private String msg;

    public static <T> R<T> ok() {
        return restResult(HttpStatus.HTTP_OK);
    }

    public static <T> R<T> ok(T data) {
        return restResult(data);
    }

    public static <T> R<T> failed() {
        return restResult(HttpStatus.HTTP_SEE_OTHER);
    }

    public static <T> R<T> failed(String msg) {
        return restResult(HttpStatus.HTTP_SEE_OTHER, msg);
    }

    public static <T> R<T> failed(String msg, Object... args) {
        return restResult(HttpStatus.HTTP_SEE_OTHER, Strings.lenientFormat(msg, args));
    }

    public static <T> R<T> failed(ResultCode code) {
        return restResult(code.getCode(), code.getMsg());
    }

    public static <T> R<T> failed(ResultCode code, String msg) {
        return restResult(code.getCode(), msg);
    }

    public static <T> R<T> failed(ResultCode code, String msg, Object... args) {
        return restResult(code.getCode(), Strings.lenientFormat(msg, args));
    }

    private static <T> R<T> restResult(long code) {
        return new R<>(code);
    }

    private static <T> R<T> restResult(T data) {
        return new R<>(HttpStatus.HTTP_OK, data);
    }

    private static <T> R<T> restResult(long code, String msg) {
        return new R<>(code, msg);
    }

    /**
     * 必须声明public无参构造，否则会序列化失败
     */
    public R() {
    }

    private R(long code) {
        this.code = code;
    }

    private R(long code, T data) {
        this.code = code;
        this.data = data;
    }

    private R(long code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public R<T> setCode(long code) {
        this.code = code;
        return this;
    }

    public R<T> setData(T data) {
        this.data = data;
        return this;
    }

    public R<T> setMsg(String msg) {
        this.msg = msg;
        return this;
    }

    public long getCode() {
        return code;
    }

    public T getData() {
        return data;
    }

    public String getMsg() {
        return msg;
    }
}
